package com.detu.ivos.audit.service.impl;


import com.detu.ivos.application.mapper.ApplicationMapper;
import com.detu.ivos.application.pojo.entity.Application;
import com.detu.ivos.audit.mapper.AuditMapper;
import com.detu.ivos.audit.pojo.dto.AuditQuery;
import com.detu.ivos.audit.pojo.dto.AuditSaveParam;
import com.detu.ivos.audit.pojo.entity.Audit;
import com.detu.ivos.audit.pojo.vo.AuditVO;
import com.detu.ivos.audit.service.AuditService;
import com.detu.ivos.base.enums.ApplicationStatusEnum;
import com.detu.ivos.base.enums.AuditStatusEnum;
import com.detu.ivos.user.mapper.usermapper.UserMapper;
import com.detu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

@Transactional
//@Transactional是spring同宫的一个用于管理事务的注解，用来管理类或方法上的事务行为
//对数据库做操作时，可以确保方法中的所有数据库操作都在同一个事务中执行，要么都成功，要么都失败
@Slf4j
@Service
public class AuditServiceImpl implements AuditService {
    @Autowired
    AuditMapper auditMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    ApplicationMapper applicationMapper;

    @Override
    public void insertAudit(Application application) {
        log.debug("为申请单生成审批单：={}", application);
        List<Long> auditUserIdList = application.getAuditUserIdList();
        for (int i = 0; i < auditUserIdList.size(); i++) {
            Audit audit = new Audit();
            //设置申请人id
            audit.setApplicationId(application.getId());
            //设置审批人id
            audit.setAuditUserId(auditUserIdList.get(i));
            System.out.println(auditUserIdList.get(i));
            //设置审批次序
            audit.setAuditSort(i);
            //设置审批次序
            if (i == 0) {
                //待我审批
                audit.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());
            } else {
                audit.setAuditStatus(AuditStatusEnum.PENGDING.getCode());
            }

            audit.setCreateTime(new Date());
            log.debug("审批单正在生成：{}", audit);
            auditMapper.insert(audit);
        }
    }

    @Override
    public List<AuditVO> selectAuditByApplicationId(Long id) {
        return auditMapper.selectAuditByApplicationId(id);
    }

    //查询审批单信息
    @Override
    public List<AuditVO> select(AuditQuery auditQuery) {
        log.debug("查询审批单业务，参数：{}", auditQuery);
        List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);

        //遍历这个集合，为他设置审批人的名字
        for (int i = 0; i < auditVOList.size(); i++) {
            //获取每一个审批单对象
            AuditVO auditVO = auditVOList.get(i);
            //调用方法为这个审批表对象补全审批人姓名
            SetAuditNameByApplicationId(auditVO);
        }
        log.debug("查到的审批单：{}",auditVOList);
        return auditVOList;
    }

    @Override
    public void updateAuditStatus(AuditSaveParam auditSaveParam) {
        log.debug("更新审批业务，参数：{}", auditSaveParam);
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam, audit);
        audit.setUpdateTime(new Date());
        //更新当前的这个审批单,审批单的状态是30还是40是由前端传过来的
        auditMapper.updateAudit(audit);
        //准备更新此审批单对应的申请单
        Application application = new Application();
        application.setId(audit.getApplicationId());
        application.setUpdateTime(new Date());
        /* 判断是通过处理还是驳回处理 */
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())) {//通过处理
            //1.继续查当前审批单对应的其它审批单(与当前审批单批同一个申请单)
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            //2.根据申请单id,查出此申请单对应的所有未审批的审批单总数
            Integer count = auditMapper.selectRestAuditCount(auditQuery);
            if (count > 0) {
                //还有未审批的审批单
                //3.根据申请单id与审批次序+1找到下一条未审批的审批单
                auditQuery.setAuditSort(audit.getAuditSort() + 1);
                List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
                if (auditVOList != null && auditVOList.size() > 0) {
                    AuditVO auditVO = auditVOList.get(0);
                    //4.准备更新第2条审批单
                    Audit Audit2 = new Audit();
                    Audit2.setId(auditVO.getId());
                    Audit2.setAuditStatus(AuditStatusEnum.MY_PENGDING.getCode());
                    Audit2.setUpdateTime(new Date());
                    auditMapper.updateAudit(Audit2);
                }
                //5.更新申请单
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.update(application);
            } else {
                //刚刚更新的审批单是最后一个审批单了
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.update(application);
            }
        } else if (audit.getAuditStatus().equals(AuditStatusEnum.REJECT.getCode())) {//驳回处理
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId());
            List<AuditVO> auditVOList = auditMapper.selectAudit(auditQuery);
            if (auditVOList != null && auditVOList.size() > 0) {
                for (int i = 0; i < auditVOList.size(); i++) {
                    AuditVO auditVO = auditVOList.get(i);
                    if(auditVO.getAuditStatus().equals(AuditStatusEnum.PENGDING.getCode())){
                        auditMapper.deleteById(auditVO.getId());
                    }
                }
            }
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.update(application);
        }
    }

    //    定义一个方法用来获取审批人姓名
    private void SetAuditNameByApplicationId(AuditVO auditVO) {
        //1.准备空集合,分别用来保存审批人id与姓名
        List<String> auditUsernameList = new ArrayList<>();
        List<Long> auditUserIdList = new ArrayList<>();
        //获取这个审批单的申请单id
        Long applicationId = auditVO.getApplicationId();
        //通过申请表id在审批表中查询对应的审批单，保存在集合中
        List<AuditVO> auditVOList =
                auditMapper.selectAuditByApplicationId(applicationId);
        //遍历集合，根据审批人id，在用户表中查询该用户的姓名
        for (int i = 0; i < auditVOList.size(); i++) {
            //获取集合中的每一个审批单
            AuditVO auditVO1 = auditVOList.get(i);
            //获取每审批单的审批人id
            Long id = auditVO1.getAuditUserId();
            //把id存入集合中
            auditUserIdList.add(id);
            //使用审批人id，在用户表中查询该用户的姓名
            UserVO userVO = userMapper.selectById(id);
            //把用户的姓名保存在尊准备的集合中
            auditUsernameList.add(userVO.getUsername());
        }
        //使用stringJoiner对象拼接字符串
        StringJoiner stringJoiner = new StringJoiner(",");
        for (String username : auditUsernameList) {
            stringJoiner.add(username);
        }
        auditVO.setAuditUsernameList(stringJoiner.toString());
        auditVO.setAuditUserIdList(auditUserIdList);
    }
}
